# coding=utf-8
"""
读取config.ini中的日志相关配置
"""

import configparser
import traceback
from configparser import NoOptionError, NoSectionError
import os

import codecs
from typing import NoReturn

from Common.public.readfile import Readfile

BASE_DIR = os.path.dirname(
    os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
CONFIG_PATH = BASE_DIR + r"\config.ini"


class GetConfig(object):
    @staticmethod
    def get_config() -> configparser.RawConfigParser:
        config = configparser.RawConfigParser()
        with open(
                file=CONFIG_PATH, mode="rb"
        ) as f:  # 2018-6-10 BEGIN 判断文件的编码类型 如果是UTF-8 BOM格式，则将其转化为无BOM格式
            s = f.read()
        if s.startswith(codecs.BOM_UTF8):  # 带BOM的文件是以 b'\xef\xbb\xbf' 开头
            s = s[len(codecs.BOM_UTF8):]  # 截取 b'\xef\xbb\xbf' 到文件结尾
            with open(file=CONFIG_PATH, mode="wb") as f:  # 保存为无BOM格式
                f.write(s)
        coding = Readfile.get_file_coding(filepath=CONFIG_PATH).get("encoding")
        config.read(filenames=CONFIG_PATH, encoding=coding
                    )  # 2018-6-10 END 判断文件的编码类型 如果是UTF-8 BOM格式，则将其转化为无BOM格式
        return config

    def _write_config(self, config):
        """写入配置"""
        coding = Readfile.get_file_coding(filepath=CONFIG_PATH).get("encoding")
        with open(CONFIG_PATH, mode='w', encoding=coding) as f:
            config.write(f)

    def _prop_setter(self, section, option, value):
        """添加配置"""
        try:
            config = self.get_config()
            config.set(section=section, option=option, value=value)
            self._write_config(config)
        except Exception as e:
            err_msg = '...\\项目目录\\Config\\config.ini更新配置 %s.%s 选项 值 "%s" 出错。\n错误详情：\n %s' % \
                      (section, option, value, traceback.format_exc())

            raise RuntimeError(err_msg) from e  # 供web捕获异常，前台提示

    @property
    def BASE_DIR(self) -> str:
        # return self.get_config().get(section="PROJECT", option="project_dir")
        # 不在需要配置项目路径，项目迁移更加灵活。
        return BASE_DIR

    @property
    def data_style(self) -> str:
        section = "LOG"
        option = "data_style"
        default = '%Y%m%d %H:%M:%S'
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default

        return value

    @data_style.setter
    def data_style(self, value) -> NoReturn:
        section = "LOG"
        option = "data_style"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def handler_format(self) -> str:
        section = "LOG"
        option = "handler_format"
        default = '%(color)s[%(levelname)1.1s %(asctime)s %(module)s:%(lineno)d]%(end_color)s %(message)s'
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
        return value

    @handler_format.setter
    def handler_format(self, value) -> NoReturn:
        section = "LOG"
        option = "handler_format"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def file_format(self) -> str:
        section = "LOG"
        option = "file_format"
        default = '[%(levelname)1.1s %(asctime)s %(module)s:%(lineno)d] %(message)s'
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default

        return value

    @file_format.setter
    def file_format(self, value) -> NoReturn:
        section = "LOG"
        option = "file_format"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def maxBytes(self) -> int:
        section = "LOG"
        option = "maxBytes"
        default = int(1e6)
        try:
            value = eval(self.get_config().get(section=section, option=option))
        except (NoOptionError, NoSectionError):
            value = default
        return value

    @maxBytes.setter
    def maxBytes(self, value) -> NoReturn:
        section = "LOG"
        option = "maxBytes"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def backupCount(self) -> int:
        section = "LOG"
        option = "backupCount"
        default = 0
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
        return value

    @backupCount.setter
    def backupCount(self, value) -> NoReturn:
        section = "LOG"
        option = "backupCount"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def level(self) -> str:
        section = "LOG"
        option = "level"
        default = 10
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
        return value

    @level.setter
    def level(self, value) -> NoReturn:
        section = "LOG"
        option = "level"
        self._prop_setter(section=section, option=option, value=value)


Config = GetConfig()
